//
//  main.c
//  duojitest
//
//  Created by 徐志瀚 on 17/11/5.
//  Copyright © 2017年 徐志瀚. All rights reserved.
#include <stdio.h>
#include <stdlib.h>
#include "FB.h"
#define NUM 2/*进程个数*/
#define OK 1
#define ERROR 0


/*定义进程结构体QNode*/
typedef struct QNode
{
    int needtime;/*进程所需时间*/
    int cputime; /*进程周转时间*/
    int number;  /*进程名称*/
    int time;    //到达时间
    struct QNode *next;
} QNode, *QueuePtr;

typedef struct
{
    QueuePtr front;
    QueuePtr rear;
} ReadQueue;

int InitQueue(ReadQueue *q);

int DestroyQueue(ReadQueue *q);

int IsEmptyQueue(ReadQueue *q);

int InsertQueue(ReadQueue *q, QNode *e);

int DeQueue(ReadQueue *q, QNode *e);
//构造一个空队列
int InitQueue(ReadQueue *q)
{
    q->front = (QueuePtr)malloc(sizeof(QNode));
    q->rear = (QueuePtr)malloc(sizeof(QNode));
    
    if(q->front == NULL){
        fprintf(stderr, "malloc() error.\n");
        return ERROR;
    }
    
    q->front->next = NULL;
    q->rear->next = NULL;
    
    return OK;
}


int IsEmptyQueue(ReadQueue *q)//判断队列是否为空
{
    return (q->front->next == NULL && q->rear->next == NULL);
}

int InsertQueue(ReadQueue *q, QNode *e){
    QueuePtr p = (QueuePtr)malloc(sizeof(QNode));
    if(p == NULL){
        fprintf(stderr, "malloc() error.\n");
        return ERROR;
    }
    
    p->needtime = e->needtime;
    p->time=e->time;
    p->number = e->number;
    p->next = NULL;
    
    //如果队列为空
    if(IsEmptyQueue(q)){
        q->front->next = p;
        q->rear = p;
    }
    else{
        q->rear->next = p;
        q->rear = p;
    }
    return OK;
}


int DeQueue(ReadQueue *q, QNode *e)//若队列不空，则删除队头元素，用e返回其值，并返回OK
{
    if(IsEmptyQueue(q)){
        fprintf(stdout, "the queue is null.\n");
        return ERROR;
    }
    
    //注意有队头结点
    QueuePtr temp;
    temp = q->front->next;
    
    e->needtime = temp->needtime;
    e->number = temp->number;
    e->time =temp->time;
    
    q->front->next = temp->next;
    if(q->rear == temp){
        q->rear = q->front;
    }
    free(temp);
    return OK;
}

int main()
{
    QNode *pc[NUM];/*定义10个进程*/
    QNode *tmp,*tmp2,*tmp3,*tmp4;/*储存出队列的进程时间片数*/
    int i,in;
    
    QueuePtr *q1,*q2,*q3,*r;/*定义3个等待队列*/
    
    q1 = (ReadQueue*)malloc(sizeof(ReadQueue));
    q2 = (ReadQueue*)malloc(sizeof(ReadQueue));
    q3 = (ReadQueue*)malloc(sizeof(ReadQueue));
    r  =  (ReadQueue*)malloc(sizeof(ReadQueue));
    InitQueue(q1);
    InitQueue(q2);
    InitQueue(q3);
    InitQueue(r);
    int T=0;
    int count1=1;
    tmp = (QNode*)malloc(sizeof(QNode));
    tmp2 = (QNode*)malloc(sizeof(QNode));
    
    
    for(i=0; i<NUM; i++)
    {
        pc[i] = (QNode *)malloc(sizeof(QNode));
        printf("输入进程 %c需要的运行时间:",i+65);
        scanf("%d",&(pc[i]->needtime));
        printf("输入进程 %c到达时间:",i+65);
        scanf("%d",&(pc[i]->time));
        pc[i]->number = i+1;
        InsertQueue(r,pc[i]);
       
     }
    DeQueue(r, tmp);//从就绪队列r中取出第一个元素；
   // printf("结构体：%c,time :%d",tmp->number+64,tmp->time);

     //printf("输出的一个待进入q1的结构体%c\n",tmp->number+64);
    while (!(IsEmptyQueue(r)&&IsEmptyQueue(q1)&&IsEmptyQueue(q2)&&IsEmptyQueue(q3))) {
        count1++;
        //DeQueue(r, tmp);
        if (count1>=tmp->time) {
            InsertQueue(q1, tmp);//如果进程的开始时间小于现在的时间，则将进程插入到p1中；
            //printf("在外部中插入到q1%c,现在的时间：% d\n",tmp->number+64,count1);
            
            if (!IsEmptyQueue(r)) {
                DeQueue(r, tmp);//同时 输出下一个元素；
            }
           // printf("结构体：%c,time :%d",tmp->number+64,tmp->time);

             //printf("输出的一个待进入q1的结构体%c\n",tmp->number+64);
        }
   
    printf("\n*****就绪队列1*****\n");
    while(!IsEmptyQueue(q1))//当q1队列不空
    {
        count1++;
        //printf("结构体：%c,needtime :%d",tmp->number+64,tmp->time);
        if (count1>=tmp->time) {
            
            InsertQueue(q1, tmp);
           // printf("在q1中插入到q1:%c,现在的时间：% d\n",tmp->number+64,count1);
            if (!IsEmptyQueue(r)) {
                DeQueue(r, tmp);
            }

           // printf("输出的一个待进入q1的结构体%c\n",tmp->number+64);
        }
        
        DeQueue(q1,tmp2);
        //printf("结构体：%c,needtime :%d",tmp2->number+64,tmp2->needtime);

        tmp2->needtime -= 1;
        tmp2->cputime=count1+tmp2->needtime;
        printf("\n调度：%c",tmp2->number+64);
        //printf("结构体：%c,needtime :%d",tmp2->number+64,tmp2->needtime);

        if(tmp2->needtime >0){
            InsertQueue(q2,tmp2);
           // printf("将q1中的结构体：%c插入到q2中,现在的时间：% d\n",tmp2->number+64,count1);
            
        }
        else
            printf("(进程 %c 结束，所用时间%d!)\n",tmp2->number+64,tmp2->cputime - tmp2->time );
        
    }
   
    printf("\n*****就绪队列2*****\n");
    
    while(!IsEmptyQueue(q2)&&IsEmptyQueue(q1))//当q2队列不空且q1队列空；
    {
        count1+=2;
        if (count1>=tmp->time) {
            InsertQueue(q1, tmp);
            if (!IsEmptyQueue(r)) {
                DeQueue(r, tmp);
            }

        }
        
        DeQueue(q2,tmp2);
        printf("\n调度：%c",tmp2->number+64);
        tmp2->needtime -= 2;
        tmp2->cputime=count1+tmp2->needtime;
        if(tmp2->needtime >0){
            InsertQueue(q3,tmp2);
          
        }
        else
           printf("(进程 %c 结束，所用时间%d!)\n",tmp2->number+64,tmp2->cputime - tmp2->time );
        
    };
    printf("\n*****就绪队列3*****:\n");
    
    
    while(!IsEmptyQueue(q3)&&IsEmptyQueue(q1)&&IsEmptyQueue(q2))//当q3队列不空且q1和q2为空；
    {
        count1+=3;
        if (count1>=tmp->time) {
            InsertQueue(q1, tmp);
            if (!IsEmptyQueue(r)) {
                DeQueue(r, tmp);
            }

        }
        DeQueue(q3,tmp);
        printf("\n调度：%c",tmp2->number+64);
        tmp2->needtime -= 3;
        tmp2->cputime=count1+tmp2->needtime;
        if(tmp2->needtime >0){
            InsertQueue(q3,tmp2);
        }
        else
            printf("(进程 %c 结束，所用时间%d!)\n",tmp2->number+64,tmp2->cputime - tmp2->time );
    };
    printf("\n");
    
    }
    
   
    return 0;
}

